﻿/*----------------------------------------------------------------------------------------
*
*  Copyright 2019, Gao Hai Hui, <fromzeropoint@126.com>.  All rights reserved.
*  https://gitee.com/helloworldghh/xoskit.git
*  Use of this source code is governed by a MIT license
*  that can be found in the License file.
*
----------------------------------------------------------------------------------------*/
#ifndef __XOSKIT_XOS_CORE_XOS_STL_SRC_PROTOCOL_PKG_PKG_BASE_RES_H__
#define __XOSKIT_XOS_CORE_XOS_STL_SRC_PROTOCOL_PKG_PKG_BASE_RES_H__

#include "../../import/head.h"
#include "../../tools/head.h"
#include <string>

namespace xos_box
{
    class i_box_mgr;
}

namespace xos_protocol
{

    template< class CHILD, class SESSION, class DATA, class PACKAGE >
    class pkg_base_res
    {
    public:
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // 
        pkg_base_res( xos_box::i_serial * pSerial, xos_container::i_container * pContainer, int nProtocol ) :
            serial_ptr( pSerial ),
            container_ptr( pContainer ),
            n_protocol( nProtocol )
        {
            n_ret = 0;
        }

        ~pkg_base_res()
        {
        }

    public:
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //
        xos_container::i_container * container_ptr;
        xos_box::i_serial * serial_ptr;
        std::string str_err;
        int n_protocol;
        int n_ret;

    public:
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //
        int dis_compose( int nCmd, int nCookie, SESSION * pSession, xos_box::i_buf * pBuf )
        {
            CHILD * pThis = static_cast<CHILD*>( this );
            int ret = 0;

            if( ( 0 == ret ) && ( n_protocol != nCmd ) )
            {
                return 0;
            }

            if( 0 == ret )
            {
                pThis->helper_dis_compose( pBuf );
            }

            if( 0 == ret )
            {
                pThis->helper_proc( nCookie, pSession );
            }

            if( 0 == ret )
            {
                ret = compose( nCookie, pSession );
            }

            if( 0 != ret )
            {
                pSession->post_close();
                pSession = 0;
            }

            return 1;
        }

        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //
        int done( int nProtocol, DATA * pData )
        {
            CHILD * pThis = static_cast<CHILD*>( this );
            int ret = 0;

            if( ( 0 == ret ) && ( n_protocol != nProtocol ) )
            {
                return 0;
            }

            if( 0 == ret )
            {
                pThis->helper_done( pData );
            }

            return 1;
        }

        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //
        int compose( int nCookie, SESSION * pSession )
        {
            int ret = 0;

            bool bFinished = false;

            while( ( 0 == ret ) && !bFinished )
            {
                ret = compose_item( nCookie, pSession, bFinished );
            }

            return ret;
        }

    protected:
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //

        int compose_item( int nCookie, SESSION * pSession, bool & bFinished )
        {
            int ret = 0;

            CHILD * pThis = static_cast<CHILD*>( this );
            xos_box::i_buf * pBuf = container_ptr->buf();

            if( 0 == ret )
            {
                bFinished = true;
                pThis->helper_compose( nCookie, pBuf, bFinished );
            }

            if( 0 == ret )
            {
                PACKAGE pkg;
                ret = pkg.post_package( pSession, pBuf );
                pBuf = 0;
            }

            xos_stl::release_interface( pBuf );

            return ret;
        }

    public:
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //
        /*
        int helper_dis_compose( xos_box::i_buf * pBuf )
        {
            int ret = 0;
            return ret;
        }

        int helper_proc( int nCookie, SESSION * pSession )
        {
            int ret = 0;
            return ret;
        }

        int helper_compose( int nCookie, xos_box::i_buf * pBuf, bool & bFinished )
        {
            int ret = 0;
            bFinished = true;
            return ret;
        }
        
        int helper_done( DATA * pData )
        {
            int ret = 0;
            return ret;
        }
        */
    };

} // xos_protocol

#endif // __XOSKIT_XOS_CORE_XOS_STL_SRC_PROTOCOL_PKG_PKG_BASE_RES_H__
